<?php
class RegistrationController extends Zend_Controller_Action 
{
	protected $_form;
	protected $_namespace = 'RegistrationController';
    protected $_session;
    
    public function init()
    {
       $this->view->headScript()->appendFile('/js/formjs.js');
       $this->view->headLink()->appendStylesheet('/css/tooltip.css');
    }
    
    public function indexAction()
    {
    	$this->_helper->layout->setLayout('lightlayout');
    	
    	// Either re-display the current page, or grab the "next"
        // (first) sub form
        $form = $this->getCurrentSubForm();
        if (!$form) {
            $form = $this->getNextSubForm();
        }
        $this->view->form = $this->getForm()->prepareSubForm($form);
    }
    
    /**
     * Process form submission and select next subform to show
     * 
     * @return void
     */
    public function processAction()
    {
    	$this->_helper->layout->setLayout('lightlayout');
    	
    	$form = $this->getCurrentSubForm();
    	
        if (!$form) {
            return $this->_forward('index');
        }

        if (!$this->subFormIsValid($form, $this->getRequest()->getPost())) {
            $this->view->form = $this->getForm()->prepareSubForm($form);
            return $this->render('index');
        } else {
        	if($form->getValue('isOpenID') == 1) {
        		$this->_forward('loadopenidprofile');
        	}
        }
        
        $form = $this->getNextSubForm();
        if ($form) {
        	$this->view->form = $this->getForm()->prepareSubForm($form);
            return $this->render('index');
        } 
        
        // Valid form!
        // Render information in a verification page and save them
        $session = $this->getSessionNamespace();
        
        unset($session->formName);
        
        try {
            $this->register($session);
        } catch (Exception $e) {
        	$session->unsetAll();
        	
        	throw $e;
        }
        
        $session->unsetAll();
        return $this->render('verification');
    }
    
    /**
     * Check for already registered username
     * - AJAX Request
     * @return void
     */
    public function checkusernameAction()
    {
        // Disable both view and layout
        $this->_helper->viewRenderer->setNoRender();
        $this->_helper->layout->disableLayout();
        
        $username = $this->getRequest()->getParam('username');
        if (empty($username)) {
            $return = Zend_Json::encode(array('result' => false));
            $this->_response->appendBody($return);
        } else {
            $factory = Model_Factory::getInstance();
            $service = $factory->getUserService();
            $user = $service->findByUsername($username);
            
            $return = null === $user ? false : true;
            $return = Zend_Json::encode(array('result' => $return));
            $this->_response->appendBody($return);
        }
        return;
    }
      
    /**
     * Chek for valid OpenID account and retrieve from it 
     * the user profile if present.
     * 
     * @return void
     */
    public function loadopenidprofileAction()
    {
    	$this->_helper->layout->setLayout('lightlayout');
        
    	$request = $this->getRequest();
    	
    	$form = $this->getCurrentSubForm();
    	
    	$openid_action = $request->get('openid_action');
        $openid_id = $request->get('openid_identifier');
        $openid_mode = $request->get('openid_mode');
        $openid_returnTo = 'loadopenidprofile';
        $openid_identity = $request->get('openid_identity');
        
        $session = $this->getSessionNamespace();
        if ($form) {
        	$session->formName = $form->getName();
        	$formName = $session->formName;
        	
        	$values = $session->$formName;
        	$openid_action = $values['user']['openid_action'];
        	$openid_id = $values['user']['openid_identifier'];
        } else {
        	$formName = $session->formName;
        	$values = $session->$formName;
        	$values['user']['openid_identifier'] = $openid_identity;
        	$session->$formName = $values;
        }
                
        $factory = Model_Factory::getInstance();
        $authService = $factory->getAuthService();

        if (($openid_action == "login" &&  !empty($openid_id)) ||
             $openid_mode != null) {
            $result = $authService->openIDAuth($openid_id, $openid_returnTo);
            if ($result) {
            	$profile = $authService->getOpenIDProfile();
            	
                $form = $this->getNextSubForm();
                if ($profile !== null) {
                    $form->populate($profile);
                }
                $authService->logout();
                
                $this->view->form = $this->getForm()->prepareSubForm($form);
                return $this->render('index');
            }
        }
        $authService->logout();
        return $this->_forward('index');
    }
    
    /**
     * Make persistent the user account and it's profile
     * 
     * @param array $data Information to store
     * @return void
     * @throws Exception if selected username is already registered
     */
    public function register($data)
    {
    	$factory = Model_Factory::getInstance();
        $service = $factory->getUserService();
        
        $userData = $data->user['user'];
        $profileData = $data->profile['profile'];

        if (null === $service->findByUsername($userData['openid_identifier'])) {
            $user = new Model_Entity_User($userData);
            $user->setUsername($userData['openid_identifier']);
            $user->setRegisterDate(date('Y-m-d H:i:s'));
            $user->setIsEnabled("1");
                                   
            $role = new Model_Entity_Role();
            $role->setOid("1");
            $user->setRoles(array($role));
            
            $userProfile = new Model_Entity_UserProfile($profileData);                   
            $user->setUserProfile($userProfile);
                
            $service->save($user);
        } else {
        	$translate = Zend_Registry::get('Zend_Translate');
        	$msg = $translate->translate('usernameUsed');
            throw new Exception($msg);       
        }
        
        return;
    }
    
    /**
     * Get the Form
     * 
     * @return Form_UserProfile
     */
    public function getForm()
    {
        if (null === $this->_form) {
            $this->_form = new Form_Registration();
        }
        return $this->_form;
    }

    /**
     * Get the session namespace we're using
     *
     * @return Zend_Session_Namespace
     */
    public function getSessionNamespace()
    {
        if (null === $this->_session) {
            $this->_session = new Zend_Session_Namespace($this->_namespace);
        }

        return $this->_session;
    }
    
    /**
     * Get a list of forms already stored in the session
     *
     * @return array
     */
    public function getStoredForms()
    {
        $stored = array();
        foreach ($this->getSessionNamespace() as $key => $value) {
            $stored[] = $key;
        }

        return $stored;
    }

    /**
     * Get list of all subforms available
     *
     * @return array
     */
    public function getPotentialForms()
    {
        return array_keys($this->getForm()->getSubForms());
    }
    
    /**
     * What sub form was submitted? 
     *
     * @return false|Zend_Form_SubForm
     */
    public function getCurrentSubForm()
    {
        $request = $this->getRequest();
        if (!$request->isPost()) {
            return false;
        }

        foreach ($this->getPotentialForms() as $name) {
        	$data = $request->getPost($name, false);
            if ($data && is_array($data)) {
                return $this->getForm()->getSubForm($name);
            }
        }

        return false;
    }
    
    /**
     * Get the next sub form to display
     *
     * @return Zend_Form_SubForm|false
     */
    public function getNextSubForm()
    {
        $storedForms    = $this->getStoredForms();
        $potentialForms = $this->getPotentialForms();

        foreach ($potentialForms as $name) {
            if (!in_array($name, $storedForms)) {
                return $this->getForm()->getSubForm($name);
            }
        }

        return false;
    }
    
    /**
     * Is the sub form valid?
     *
     * @param  Zend_Form_SubForm $subForm
     * @param  array $data
     * @return bool
     */
    public function subFormIsValid(Zend_Form_SubForm $subForm, array $data)
    {
        $name = $subForm->getName();
        if ($subForm->isValid($data)) {
            $this->getSessionNamespace()->$name = $subForm->getValues();
            return true;
        }

        return false;
    }
    
    /**
     * Is the full form valid?
     *
     * @return bool
     */
    public function formIsValid()
    {
        $data = array();
        foreach ($this->getSessionNamespace() as $key => $info) {
            $data[$key] = $info;
        }

        return $this->getForm()->isValid($data);
    }
}
